added SSCLI 1.0
[windows-sources.git] / shared source / vb / language / shared / refcountedptr.h
blob1ad0ecc96dc0b2f6df969169bd07fe9539e9ca12
1 //-------------------------------------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // Ref Counted Pointer.
6 //
7 // Only safe for single threaded operations
8 //
9 //-------------------------------------------------------------------------------------------------
11 #pragma once
13 template <class T>
14 class RefCountedPtr
16 private:
17 struct Data
19 NEW_CTOR_SAFE()
21 Data() :
22 pData(NULL),
23 Count(0)
27 ~Data()
29 if ( pData )
31 delete pData;
35 T *pData;
36 SafeInt<unsigned int> Count;
39 public:
41 RefCountedPtr()
42 : m_pData(NULL)
47 explicit RefCountedPtr(T* pData)
49 m_pData = new Data();
50 m_pData->pData = pData;
51 m_pData->Count = 1;
54 RefCountedPtr(const RefCountedPtr<T> &other)
55 : m_pData(NULL)
57 // Increment count before assigning the pointer. Pointer assignment is
58 // exception safe but incrementing the count is not. If incrementing the
59 // count overflows then the count would be N and the number of references
60 // would be N+1 resulting in a double free.
61 if ( other.m_pData )
63 other.m_pData->Count +=1;
64 m_pData = other.m_pData;
68 ~RefCountedPtr()
70 Release();
73 operator T*() const
75 return m_pData ? m_pData->pData : NULL;
78 T& operator *() const
80 VSASSERT(m_pData, "Accessing NULL Pointer");
81 return *(m_pData->pData);
84 T* operator ->()
86 VSASSERT(m_pData, "Accessing NULL Pointer");
87 return m_pData->pData;
90 const T* operator ->() const
92 VSASSERT(m_pData, "Accessing NULL Pointer");
93 return m_pData->pData;
96 const RefCountedPtr<T>& operator=(const RefCountedPtr<T>& other)
98 RefCountedPtr<T> temp(other);
99 TemplateUtil::Swap(&m_pData, &temp.m_pData);
100 return *this;
103 const RefCountedPtr<T>& operator=(const T& other)
105 RefCountedPtr<T> temp(new T(other));
106 TemplateUtil::Swap(&m_pData, &temp.m_pData);
107 return *this;
110 const RefCountedPtr<T>& operator=(T* ptr)
112 RefCountedPtr<T> temp(ptr);
113 TemplateUtil::Swap(&m_pData, &temp.m_pData);
114 return *this;
117 void Attach( _In_ T *pData)
119 Release();
120 RefCountedPtr<T> temp(pData);
121 *this = temp;
124 void Release()
126 if ( m_pData )
128 VSASSERT(m_pData->Count.Value() != 0, "RefCountedPtr count error");
130 m_pData->Count -= 1;
131 if ( 0 == m_pData->Count.Value() )
133 delete m_pData;
135 m_pData = NULL;
139 T* GetData() const
141 return (m_pData) ? m_pData->pData : NULL;
144 private:
146 void RemoveReference()
150 Data* m_pData;